package com.w1.security.filter;




import com.w1.security.handler.AuthManager;
import com.w1.security.handler.authHandler.AuthFailureHandler;
import com.w1.security.handler.authHandler.AuthSuccessHandler;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.stereotype.Component;

import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 第一次登陆，认证拦截的入口
 * @author mingyifan
 * @date 2022-02-24 16:05
 */

@Component
public class AuthProcessingFilter extends AbstractAuthenticationProcessingFilter {

    /**
     * @param authenticationManager: 认证管理器
     * @param authSuccessHandler: 认证成功处理
     * @param authFailureHandler: 认证失败处理
     */
    public AuthProcessingFilter(AuthManager authenticationManager, AuthSuccessHandler authSuccessHandler, AuthFailureHandler authFailureHandler) {
        //只拦截特定请求
        super(new AntPathRequestMatcher("/login", "POST"));
        this.setAuthenticationManager(authenticationManager);
        this.setAuthenticationSuccessHandler(authSuccessHandler);
        this.setAuthenticationFailureHandler(authFailureHandler);
    }

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
        //判断header中的auth属性是否可以被解密
        AbstractAuthenticationToken authRequest;
        try {
            String username = request.getParameter("username");
            String password = request.getParameter("password");
            //解密成后塞到Authentication的getCredentials()可以获取的属性中
            authRequest = new UsernamePasswordAuthenticationToken(username, password);
            authRequest.setDetails(authenticationDetailsSource.buildDetails(request));
        } catch (Exception e) {
            throw new AuthenticationServiceException(e.getMessage());
        }
        //传给manager
        return this.getAuthenticationManager().authenticate(authRequest);
    }
}
